﻿using System;
using System.Collections.Generic;
using Web7.Ioc;
using System.Web.Mvc;
using Autofac.Integration.Mvc;
using Web7.Extensions;

namespace Web7.Core.IOC.Autofac
{
    public class AutofacMvcResolver : AbstractWeb7DependencyResolver,IDependencyResolver
    {
        private readonly AutofacResolver _dependencyResolver;
        private readonly AutofacDependencyResolver _mvcSpecificDependencyResolver;

        public AutofacMvcResolver(IWeb7DependencyResolver resolver)
            : base(resolver)
        {
            var incomingUmbracoResolver = resolver as AutofacResolver;
            if (incomingUmbracoResolver == null)
                throw new ArgumentException("Must be of type 'Web7.Core.InversionOfControl.Autufac.AutofacResolver'", "resolver");

            _mvcSpecificDependencyResolver = new AutofacDependencyResolver(incomingUmbracoResolver.AutofacContainer);
            _dependencyResolver = new AutofacResolver(_mvcSpecificDependencyResolver.RequestLifetimeScope);
        }

        /// <summary>
        /// 解析单独注册的服务，支持任意对象创建。
        /// </summary>
        /// <returns>
        /// 所要求的服务对象，如果获取到了则返回，否则， <c>null</c>.
        /// </returns>
        /// <param name="serviceType">需要解析的类型</param>
        public object GetService(Type serviceType)
        {
            return _mvcSpecificDependencyResolver.GetService(serviceType);
        }

        /// <summary>
        /// 解析多个注册的服务
        /// </summary>
        /// <returns>
        /// 所要求的服务对象
        /// </returns>
        /// <param name="serviceType">请求的服务类型</param>
        public IEnumerable<object> GetServices(Type serviceType)
        {
            return _mvcSpecificDependencyResolver.GetServices(serviceType);
        }

        /// <summary>解析一个所需的已注入类型</summary>
        /// <typeparam name="T">已注入的类型</typeparam>
        /// <returns>该类型的实例<typeparamref name="T"/>.</returns>
        public override T Resolve<T>()
        {
            return _dependencyResolver.Resolve<T>();
        }

        /// <summary>
        /// 解析多个所需的已注入类型
        /// </summary>
        /// <typeparam name="T">已注入的类型</typeparam>
        /// <returns>该类型的实例集合</returns>
        public override IEnumerable<T> ResolveAll<T>()
        {
            return _dependencyResolver.ResolveAll<T>();
        }

        public override T Resolve<T>(string name)
        {
            return _dependencyResolver.Resolve<T>(name);
        }

        public override object Resolve(Type type)
        {
            return _dependencyResolver.Resolve(type);
        }

        public override IEnumerable<object> ResolveAll(Type type)
        {
            return _dependencyResolver.ResolveAll(type);
        }

        public override object Resolve(Type type, string name)
        {
            return _dependencyResolver.Resolve(type, name);
        }
        #region Overrides of DisposableObject

        protected override void DisposeResources()
        {
            _dependencyResolver.IfNotNull(x => x.Dispose());
            _mvcSpecificDependencyResolver.IfNotNull(x => x.RequestLifetimeScope.IfNotNull(y => y.Dispose()));
        }

        #endregion
    }
}
